package com.flame.core.utils;

import java.security.Security;
import java.util.HashMap;
import java.util.Map;

import com.flame.core.utils.cipher.AesCipher;
import com.flame.core.utils.cipher.Base64Cipher;
import com.flame.core.utils.cipher.FlameCipher;
import com.flame.core.utils.cipher.Md5Cipher;
import com.flame.core.utils.cipher.RsaCipher;
import com.flame.core.utils.cipher.Sm2Cipher;
import com.flame.core.utils.cipher.Sm3Cipher;
import com.flame.core.utils.cipher.Sm4Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * CryptionUtils
 *
 * @author wuxintong
 * @since 2022/11/28
 */
public final class CipherUtils {

    static {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
    }

    public static final String AES = "AES";

    public static final String RSA = "RSA";

    public static final String MD5 = "MD5";

    public static final String BASE64 = "BASE64";

    public static final String SM2 = "SM2";

    public static final String SM3 = "SM3";

    public static final String SM4 = "SM4";

    private static final Map<String, FlameCipher> CIPHER_MAP = new HashMap<>();

    static {
        CIPHER_MAP.put(AES, new AesCipher());
        CIPHER_MAP.put(RSA, new RsaCipher());
        CIPHER_MAP.put(MD5, new Md5Cipher());
        CIPHER_MAP.put(BASE64, new Base64Cipher());
        CIPHER_MAP.put(SM2, new Sm2Cipher());
        CIPHER_MAP.put(SM3, new Sm3Cipher());
        CIPHER_MAP.put(SM4, new Sm4Cipher());
    }

    private CipherUtils() {
    }

    public static String md5Encrypt(String data) throws Exception {
        return CIPHER_MAP.get(MD5).encrypt(data);
    }

    public static String base64Encrypt(String data) throws Exception {
        return CIPHER_MAP.get(BASE64).encrypt(data);
    }

    public static String base64Decrypt(String data) throws Exception {
        return CIPHER_MAP.get(BASE64).decrypt(data);
    }

    public static String aesEncrypt(String data) throws Exception {
        return CIPHER_MAP.get(AES).encrypt(data);
    }

    public static String aesEncrypt(String data, String key) throws Exception {
        return CIPHER_MAP.get(AES).encrypt(data, key);
    }

    public static String aesDecrypt(String data) throws Exception {
        return CIPHER_MAP.get(AES).decrypt(data);
    }

    public static String aesDecrypt(String data, String key) throws Exception {
        return CIPHER_MAP.get(AES).decrypt(data, key);
    }

    public static String rsaEncrypt(String data) throws Exception {
        return CIPHER_MAP.get(RSA).encrypt(data);
    }

    public static String rsaEncrypt(String data, String publicKey) throws Exception {
        return CIPHER_MAP.get(RSA).encrypt(data, publicKey);
    }

    public static String rsaDecrypt(String data) throws Exception {
        return CIPHER_MAP.get(RSA).decrypt(data);
    }

    public static String rsaDecrypt(String data, String privateKey) throws Exception {
        return CIPHER_MAP.get(RSA).decrypt(data, privateKey);
    }

    public static String sm2Encrypt(String data) throws Exception {
        return CIPHER_MAP.get(SM2).encrypt(data);
    }

    public static String sm2Decrypt(String data) throws Exception {
        return CIPHER_MAP.get(SM2).decrypt(data);
    }

    public static String sm2Encrypt(String data, String publicKey) throws Exception {
        return CIPHER_MAP.get(SM2).encrypt(data, publicKey);
    }

    public static String sm2Decrypt(String data, String privateKey) throws Exception {
        return CIPHER_MAP.get(SM2).decrypt(data, privateKey);
    }

    public static String sm3Encrypt(String data) throws Exception {
        return CIPHER_MAP.get(SM3).encrypt(data);
    }

    public static String sm4Encrypt(String data) throws Exception {
        return CIPHER_MAP.get(SM4).encrypt(data);
    }

    public static String sm4Encrypt(String data, String key) throws Exception {
        return CIPHER_MAP.get(SM4).encrypt(data, key);
    }

    public static String sm4Decrypt(String data) throws Exception {
        return CIPHER_MAP.get(SM4).decrypt(data);
    }

    public static String sm4Decrypt(String data, String key) throws Exception {
        return CIPHER_MAP.get(SM4).decrypt(data, key);
    }
}
